package UILayer;
import java.util.Scanner;
import CtrLayer.LeaseCtr;
import java.util.ArrayList;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import ModelLayer.CustomerCollection;
import ModelLayer.CurrentAccount;


/**
 * Write a description of class LeaseUI here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class LeaseUI
{
    LeaseCtr lease_ctr;

    /**
     * Constructor for objects of class LeaseUI
     */
    public LeaseUI()
    {
        lease_ctr = new LeaseCtr();
    }
    
    
    
    public void start_lease_menu()
    {
        boolean exit = false;
        boolean is_manager = !(CurrentAccount.give_rank().equals("employee"));
        while(!(exit))
        {
            int choice = write_lease_menu(is_manager);
            if(is_manager)
            {
                switch(choice)
                {
                    case 1 :    create_lease();
                                break;
                    case 2 :    close_lease();
                                break;
                    case 3 :    print_lease();
                                break;
                    case 4 :    print_open_leases();
                                break;
                    case 5 :    print_closed_leases();
                                break;
                    case 6 :    add_new_machine(is_manager);
                                break;
                    case 7 :    manage_machines();
                                break;
                    case 8 :    delete_machine();
                                break;
                    case 9 :    print_machine();
                                break;
                    case 10 :   print_all_machines();
                                break;
                    case 11 :   manage_unfinished_machines();
                                break;
                    default:    exit = true;  
                                break;
                }
            }
            else
            {
                switch(choice)
                {
                    case 1 :    create_lease();
                                break;
                    case 2 :    close_lease();
                                break;
                    case 3 :    print_lease();
                                break;
                    case 4 :    print_open_leases();
                                break;
                    case 5 :    print_closed_leases();
                                break;
                    case 6 :    add_new_machine(is_manager);
                                break;
                    case 7 :    manage_machines();
                                break;
                    case 8 :    delete_machine();
                                break;
                    case 9 :    print_machine();
                                break;
                    case 10 :   print_all_machines();
                                break;
                    default:    exit = true;  
                                break;
                }
            }


        }
        lease_ctr.save_data();
        System.out.println("\f");           // Needs checking if necessary
    }       
    
    
                
                                               
                            
    private int write_lease_menu(boolean is_manager)
    {
        System.out.println("\f***ACCOUNT MENU***");
        System.out.println("Press (1) to register new lease.");
        System.out.println("Press (2) to close a lease");
        System.out.println("Press (3) to display a particular lease.");
        System.out.println("Press (4) to display active leases.");
        System.out.println("Press (5) to display closed leases.");
        System.out.println("Press (6) to add new machine.");
        System.out.println("Press (7) to edit machines data.");
        System.out.println("Press (8) to delete a machine.");
        System.out.println("Press (9) to dispaly a particular machine.");
        System.out.println("Press (10) to display all machines.");
        if(is_manager)
        {
            System.out.println("Press (11) to manage unfinished machines.");
        }
        System.out.println("Press any other number to exit.");
        return int_input();
    }
    
    private void manage_unfinished_machines()
    {
        boolean wrong = true;
        int choice;
        while(wrong)
        {
            System.out.println("\fPress (1) to display all unfinished machines.");
            System.out.println("Press (2) to finish adding a machine.");
            System.out.println("Press any other number to exit.");
            choice = int_input();
            switch(choice)
            {
                case 1 :    display_unfinished_machines();
                            break;
                case 2 :    finish_machine();
                            break;
                default:    wrong = false;
                            break;
            }
        }
    }
        
    /***********************************************************INPUT READERS**************************************************************/
    private int int_input()
    {
        int input = 0;
        boolean ok = false;
        Scanner keyboard = new Scanner(System.in);
        while(!(ok))
        {
            try
            {
                input = keyboard.nextInt();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must provide a valid input.\nYou have to type a number");
                keyboard.nextLine();
            }
        }
        return input;
    }
    
    private double double_input()
    {
        double input = 0;
        boolean ok = false;
        Scanner keyboard = new Scanner(System.in);
        while(!(ok))
        {
            try
            {
                input = keyboard.nextDouble();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must provide a valid input.\nYou have to type a number");
                keyboard.nextLine();
            }
        }
        return input;
    }
    
    private String string_input()
    {
        Scanner keyboard = new Scanner(System.in);
        String output;
        while((output = keyboard.nextLine()).equals(""))
        {
            
        }
        return output;
    }
    
    private String input_lease_id()
    {
        System.out.println("Please write the ID of a desired lease or write (0) to return.");
        String id = "" + int_input();
        return  id;
    }
    
    private String input_machine_id()
    {
        System.out.println("Please write the ID of a desired machine or write (0) to return.");
        String id = "" + int_input();
        return  id;
    }
    
    private String input_return_date()
    {
        System.out.println("Please write the date on which machines are to be returned.\nWrite the date in dd/mm/yyyy format.");
        String return_date = "";
        Date current_date = new Date();
        String new_return_date;
        boolean wrong = true;
        while (wrong)
        {            
             return_date = string_input();
             if(return_date.matches("[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]"))
             {
                 SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
                 sdf.setLenient(false);
                try 
                {
                    Date date = sdf.parse(return_date);
                    if(date.getTime() <= current_date.getTime())
                    {
                        System.out.println("Inputed date is before the date of creation of the lease.\nType a correct date:");
                    }
                    else
                    {
                        wrong = false;
                    }
         
                } 
                catch (ParseException e) 
                {
                    System.out.println("The date is incorrect, please type it again:");
                }

             }
             else
             {
                 System.out.println("The date format is incorrect, please type it again:");
             }
        }
        return return_date;
    }
    
    private double input_price_per_day()
    {
        System.out.println("Please write the price per day of leasing of this machine:");
        return double_input();
    }
    
    private String input_customer_id()
    {
        System.out.println("Input the ID of a customer that requested a lease. Press(0) to exit.");
        String customer_id = "" + int_input();
        return customer_id;
    }
    
    private String input_name()
    {
        System.out.println("Please write the name of the machine:");
        return string_input();
    }
    
    private boolean input_check()
    {
        String input = "";
        System.out.println("Type (y) for yes and (n) for no:");
        while(!((input = string_input()).equals("y") || input.equals("n")))
        {
            System.out.println("You provided incorrect input.");
        }
        
        if(input.equals("y"))
        {
            return true;
        }
        return false;
    }

    /*********************************************MENU FUNCTIONS*************************************************/
    
    
    private void create_lease()
    {
        String customer_id;
        while(!(((customer_id = input_customer_id()).equals("0") || CustomerCollection.existing_customer(customer_id))))
        {
             System.out.println("There is no such customer.");
        }
        
        if(!(customer_id.equals("0")))
        {
            String return_date = input_return_date();
            ArrayList<String> ids = add_machine_to_lease();
            if(!(ids.isEmpty()))
            {
                String id = lease_ctr.create_lease(return_date, ids);
                CustomerCollection.add_lease_to_customer(customer_id, id);
            }
        }
    }
    
    private void close_lease()
    {
        String id;
        if(!((id = check_for_lease()).equals("0")))
        {
            if(!(lease_ctr.is_lease_closed(id)))
            {
                String state = lease_ctr.return_date_control(id);
                boolean sure = true;
                boolean recalculate_cost = false;
                if(state.equals("before"))
                {
                    System.out.println("You are trying to close a lease which return date has not yet came.\nAre you sure you want to do this?");
                    sure = input_check();
                    if(sure)
                    {
                        System.out.println("Do you wish to subtract the payment for not leased days from total cost of the lease?");
                        recalculate_cost = input_check();
                    }
                }
                else if(state.equals("after"))
                {
                    System.out.println("You are closing a lease after it's return date.\nDo you wish to add the payment for additional days to the total cost of the lease?");
                    recalculate_cost = input_check();
                }
                if(sure)
                {
                    lease_ctr.close_order(id, recalculate_cost);
                    System.out.println("The leased was successfully closed!");
                    wait_for_input();
                }
            }
            else
            {
                System.out.println("This lease was already closed.");
                wait_for_input();
            }
            
        }
    }
    
    private void print_lease()
    {
        String id;
        if(!((id = check_for_lease()).equals("0")))
        {
            System.out.println(lease_ctr.display_lease(id));
            wait_for_input();
        }
    }
    
    private void print_open_leases()
    {
        System.out.println(lease_ctr.display_open_leases());
        wait_for_input();
    }
    
    private void print_closed_leases()
    {
        System.out.println(lease_ctr.display_closed_leases());
        wait_for_input();
    }
    
    private void add_new_machine(boolean is_manager)
    {
        String name = input_name();
        double price_per_day = 0;
        if(is_manager)
        {
            price_per_day = input_price_per_day();
        }
        
        if (lease_ctr.add_machine(name, price_per_day))
        {
            System.out.println("The machine was successfully added!");
        }
        else
        {
            System.out.println("The machine was not added.");
        }
        wait_for_input();
    }
    
    private void manage_machines()
    {
        String id;
        if(!((id = check_for_machine()).equals("0")))
        {
            String name = input_name();
            double price_per_day = input_price_per_day();
            lease_ctr.edit_machine(id, name, price_per_day);
        }
    }
    
    
    private void delete_machine()
    {
        String id;
        if(!((id = check_for_machine()).equals("0")))
        {
            if(lease_ctr.is_machine_leased(id))
            {
                System.out.println("This machine is currently leased. You cannot delete leased machines.");
                wait_for_input();
            }
            else
            {
                if(lease_ctr.delete_machine(id))
                {
                    System.out.println("The machine was successfully deleted");
                    wait_for_input();
                }
                else
                {
                    System.out.println("The machine was not deleted.");
                    wait_for_input();
                }
            }
        }
    }
    
    private void print_machine()
    {
        String id;
        if(!((id = check_for_machine()).equals("0")))
        {
            if(lease_ctr.is_machine_unfinished(id))
            {
                System.out.println("The inputting of machine into the system has not been finished.\nThe price of the lease of the machine still needs to be inserted.");
            }
            System.out.println(lease_ctr.display_machine(id));
            wait_for_input();
        }
    }
    
    private void print_all_machines()
    {
        System.out.println(lease_ctr.display_all_machines());
        wait_for_input();
    } 
    
    private void display_unfinished_machines()
    {
        System.out.println(lease_ctr.display_unfinished_machines());
        wait_for_input();
    }
    
    private void finish_machine()
    {
        String id;
        while(!((id = check_for_machine()).equals("0") || lease_ctr.is_machine_unfinished(id)))
        {
            System.out.println("This machine does not require finishing.");
        }
        if(!(id.equals("0")))
        {
            lease_ctr.finish_machine(id, input_price_per_day());
        }
    }
    
    private ArrayList<String> add_machine_to_lease()
    {
        ArrayList<String> ids = new ArrayList<>();
        boolean exit = false;
        String id;
        while(!(exit))
        {
            System.out.println("\fPress (1) to add new machine to lease.");
            System.out.println("Press (2) to finish.");
            int choice = int_input();
            if(choice == 1)
            {
                id = check_for_machine();
                if(!(lease_ctr.is_machine_unfinished(id)))
                {
                    if(!(id.equals("0")))
                    {
                        if(!(ids.contains(id)))
                        {
                            if(!(lease_ctr.is_machine_leased(id)))
                            {
                                if(ids.add(id))
                                {
                                    System.out.println("The machine was successfully added!\n");
                                    wait_for_input();
                                }
                            }
                            else
                            {
                                System.out.println("The machine is unavailable. \nIt has already been leased.");
                                wait_for_input();
                            }
                        }
                        else
                        {
                            System.out.println("You already added this machine.");
                            wait_for_input();
                        }
                    }
                }
                else
                {
                    System.out.println("The input of this machine into the system has not yet been finished.\nYou cannot add unfinished machines into leases.");
                    wait_for_input();
                }
            }
            else if(choice == 2)
            {
                boolean do_i = false;
                if(ids.isEmpty())
                {
                    System.out.println("You haven't added any machines and therefore the lease will not be created. \nDo you wish to add any machines?");
                    do_i = input_check();
                }
                if(!(do_i))
                {
                    exit = true;
                }
            } 
        }
        return ids;
    }
            
    private void wait_for_input()
    {
        System.out.println("\nPRESS ENTER TO CONTINUE\n");
        Scanner keyboard = new Scanner(System.in);
        keyboard.nextLine();
    }
    
    private String check_for_machine()
    {
        String id;
        while(!(lease_ctr.is_such_machine_id(id = input_machine_id())))
        {
            if(id.equals("0"))
            {
                return id;
            }
            System.out.println("There is no machine with this ID");
        }
        return id;
    }
    
    private String check_for_lease()
    {
        String id;
        while(!(lease_ctr.is_such_lease_id(id = input_lease_id())))
        {
            if(id.equals("0"))
            {
                return id;
            }
            System.out.println("There is no lease with this ID:");
        }
        return id;
    }
            
}
